<template>
  <el-dialog v-model="dialogVisible" title="编辑角色" width="500px" :close-on-click-modal="false" @close="handleClose">
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px" @submit.prevent="handleSubmit">
      <el-form-item label="角色名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入角色名称" clearable maxlength="50" show-word-limit />
      </el-form-item>
      <el-form-item label="分配菜单">
        <el-select
          v-model="formData.menuIds"
          multiple
          placeholder="请选择要分配的菜单（可选）"
          style="width: 100%"
          :loading="menuLoading"
          clearable
          collapse-tags
          collapse-tags-tooltip
        >
          <el-option v-for="m in menuList" :key="m.id" :label="m.name" :value="m.id" />
        </el-select>
        <div class="form-tip">
          <el-text size="small" type="info">可以为角色分配多个菜单，也可以暂时不分配</el-text>
        </div>
      </el-form-item>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">
          {{ loading ? "更新中..." : "确定" }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { useRoleStore } from "@/stores/role";
import { menuApi } from "@/apis/menu";
import { roleApi } from "@/apis/role";
import type { Role, UpdateRoleRequest } from "@/types/role";
import type { Menu } from "@/types/menu";

interface Props {
  modelValue: boolean;
  role: Role | null;
}

interface Emits {
  (e: "update:modelValue", value: boolean): void;
  (e: "success"): void;
}

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

// Store
const roleStore = useRoleStore();

// 响应式数据
const dialogVisible = ref(false);
const loading = ref(false);
const formRef = ref<FormInstance>();
const menuLoading = ref(false);
const menuList = ref<Menu[]>([]);

// 表单数据
const formData = reactive<UpdateRoleRequest>({
  name: "",
  menuIds: [],
});

// 表单验证规则
const formRules: FormRules = {
  name: [
    { required: true, message: "请输入角色名称", trigger: "blur" },
    { min: 2, max: 50, message: "角色名称长度在 2 到 50 个字符", trigger: "blur" },
  ],
};

// 监听 modelValue 变化
watch(
  () => props.modelValue,
  (newVal) => {
    dialogVisible.value = newVal;
  },
  { immediate: true },
);

// 监听 dialogVisible 变化
watch(dialogVisible, (newVal) => {
  emit("update:modelValue", newVal);
});

// 监听 role 变化，填充表单数据
watch(
  () => props.role,
  async (newRole) => {
    if (newRole) {
      formData.name = newRole.name;
      // 打开时加载菜单列表
      try {
        menuLoading.value = true;
        const res = await menuApi.getAllMenus();
        menuList.value = Array.isArray(res.data) ? res.data : [];
      } catch (e) {
        console.error("加载菜单列表失败", e);
      } finally {
        menuLoading.value = false;
      }
      // 预填菜单选择：优先使用 props.role.menus，如果没有则再请求详情
      if (Array.isArray(newRole.menus) && newRole.menus.length > 0) {
        formData.menuIds = newRole.menus.map((m) => m.id);
      } else {
        try {
          const detail = await roleApi.getRole(newRole.id);
          const data = (detail as any).data ?? detail;
          if (Array.isArray(data?.menus)) {
            formData.menuIds = data.menus.map((m: any) => m.id);
          }
        } catch (e) {
          console.warn("获取角色详情进行预填失败", e);
        }
      }
    }
  },
  { immediate: true },
);

// 重置表单
const resetForm = () => {
  formData.name = "";
  formRef.value?.resetFields();
};

// 关闭对话框
const handleClose = () => {
  dialogVisible.value = false;
  resetForm();
};

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value || !props.role) return;

  try {
    const valid = await formRef.value.validate();
    if (!valid) return;

    loading.value = true;
    await roleStore.updateRole(props.role.id, formData);

    ElMessage.success("角色更新成功");
    emit("success");
    handleClose();
  } catch (error) {
    console.error("Failed to update role:", error);
    ElMessage.error("角色更新失败");
  } finally {
    loading.value = false;
  }
};
</script>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>
